package com.yixin.hospital.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.entity.bo.UserDeptWorkAddressJobOffice;
import com.yixin.hospital.entity.domain.*;
import com.yixin.hospital.entity.dto.req.drugdepository.DrugDepositoryAddReqDTO;
import com.yixin.hospital.entity.dto.req.drugdepository.DrugDepositoryEditReqDTO;
import com.yixin.hospital.entity.vo.DeptListDrugDepVO;
import com.yixin.hospital.entity.vo.DrugDepositoryVo;
import com.yixin.hospital.mapper.DrugDepositoryMapper;
import com.yixin.hospital.service.*;
import com.yixin.hospital.utils.CaffeineUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.yixin.hospital.common.Constant.USER_CACHE;
import static com.yixin.hospital.enums.ResponseCodeEnum.DEPT_DEPOSITORY_EXIT;

/**
* @author Administrator
* @description 针对表【drug_depository(药品仓库表)】的数据库操作Service实现
* @createDate 2024-04-16 14:53:45
*/
@Service
@Slf4j
public class DrugDepositoryServiceImpl extends ServiceImpl<DrugDepositoryMapper, DrugDepository>
    implements DrugDepositoryService{

    @Resource
    private DrugDepositoryDutyAuthService drugDepositoryDutyAuthService;
    @Resource
    private DrugDepositoryUserAuthService drugDepositoryUserAuthService;
    @Resource
    private JobDutyService jobDutyService;
    @Resource
    private DeptService deptService;
    @Resource
    private UserService userService;

    @Override
    public ApiResult<List<DrugDepositoryVo>> allDropList() {
        List<DrugDepository> list = this.list();
        List<DrugDepositoryVo> resp = new ArrayList<>();
        for (DrugDepository drugDepository : list) {
            LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Dept::getId, drugDepository.getDept());
            Dept dept = deptService.getOne(queryWrapper);
            LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(User::getId, drugDepository.getManagerUserId());
            User user = userService.getOne(userWrapper);
            DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
            BeanUtils.copyProperties(drugDepository, drugDepositoryVo);
            drugDepositoryVo.setDeptName(dept.getName());
            drugDepositoryVo.setManagerUserName(user.getName());
            resp.add(drugDepositoryVo);
        }
        return ApiResult.success(resp);
    }

    @Override
    public ApiResult<?> add(DrugDepositoryAddReqDTO drugDepositoryAddReqDTO, String userName) {
        List<DrugDepository> list = this.list(new LambdaQueryWrapper<DrugDepository>().eq(DrugDepository::getDept, drugDepositoryAddReqDTO.getDept()));
        if (!CollectionUtils.isEmpty(list)) return ApiResult.error(DEPT_DEPOSITORY_EXIT);

        DrugDepository drugDepository = new DrugDepository();
        BeanUtils.copyProperties(drugDepositoryAddReqDTO, drugDepository);

        drugDepository.setCreatedBy(userName);
        drugDepository.setUpdatedBy(userName);
        this.save(drugDepository);
        return ApiResult.success();
    }

    @Override
    public ApiResult<?> edit(DrugDepositoryEditReqDTO drugDepositoryEditReqDTO, String userName) {
        //        List<DrugDepository> list = drugDepositoryService.list(new LambdaQueryWrapper<DrugDepository>().eq(DrugDepository::getDept, drugDepositoryEditReqDTO.getDept()));
//        if (!CollectionUtils.isEmpty(list)) {
//            return ApiResult.error(DEPT_DEPOSITORY_EXIT);
//        }
        DrugDepository drugDepository = new DrugDepository();
        BeanUtils.copyProperties(drugDepositoryEditReqDTO, drugDepository);
        drugDepository.setUpdatedBy(userName);
        this.updateById(drugDepository);
        return ApiResult.success();
    }

    @Override
    public ApiResult<List<DeptListDrugDepVO>> deptListByDeptId(Long deptId) {
        //        List<Long> deptIds = new ArrayList<>();
//        deptIds.add(deptId);
//        getDeptAll(deptId, deptIds);
        // 从子部门所有库 改成 只查登录部门的库
        List<DrugDepository> list = this.list(new LambdaQueryWrapper<DrugDepository>().in(DrugDepository::getDept, Arrays.asList(deptId)));
        List<DeptListDrugDepVO> deptListDrugDepVOS = BeanUtil.copyToList(list, DeptListDrugDepVO.class);
        for (DeptListDrugDepVO deptListDrugDepVO : deptListDrugDepVOS) {
            deptListDrugDepVO.setDeptName(deptService.getById(deptListDrugDepVO.getDept()).getName());
        }
        return ApiResult.success(deptListDrugDepVOS);
    }

    @Override
    public ApiResult<List<DrugDepositoryVo>> getAvailableListByOptType(Integer optType, Long userId) {
        List<DrugDepositoryUserAuth> userAuthList = drugDepositoryUserAuthService.list(new LambdaQueryWrapper<DrugDepositoryUserAuth>().eq(DrugDepositoryUserAuth::getUserId, userId).eq(DrugDepositoryUserAuth::getOptType, optType).orderByAsc(DrugDepositoryUserAuth::getDrugDepositoryId));
        Set<Long> jobUserAuthIdList = userAuthList.stream().map(DrugDepositoryUserAuth::getDrugDepositoryId).collect(Collectors.toSet());

        // 获取当前用户登录职务 有该操作权限
        List<UserDeptWorkAddressJobOffice> loginList = (List<UserDeptWorkAddressJobOffice>) CaffeineUtils.get(USER_CACHE);
        UserDeptWorkAddressJobOffice loginUser = loginList.stream().filter(u -> u.getUserId().equals(userId)).collect(Collectors.toList()).get(0);
        Long jobDutyId = loginUser.getJobDutyId();
        List<DrugDepositoryDutyAuth> JobDutyAuthList = drugDepositoryDutyAuthService.list(new LambdaQueryWrapper<DrugDepositoryDutyAuth>()
                .eq(DrugDepositoryDutyAuth::getJobDutyId, jobDutyId)
                .eq(DrugDepositoryDutyAuth::getOptType, optType));
        Set<Long> jobDutyAuthIdList = JobDutyAuthList.stream().map(DrugDepositoryDutyAuth::getDrugDepositoryId).collect(Collectors.toSet());
        List<Long> containsIds = jobUserAuthIdList.stream()
                .filter(jobDutyAuthIdList::contains)
                .collect(Collectors.toList());

        List<DrugDepositoryVo> resp = new ArrayList<>();
        for (Long drugDepositoryId : containsIds) {
            DrugDepository drugDepository = this.getById(drugDepositoryId);
            DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
            BeanUtils.copyProperties(drugDepository, drugDepositoryVo);
            resp.add(drugDepositoryVo);
        }
        return ApiResult.success(resp);
    }

    private void getDeptAll(Long deptId, List<Long> deptIds){
        List<Dept> deptList = deptService.list(new LambdaQueryWrapper<Dept>().eq(Dept::getPid, deptId));
        for (Dept dept : deptList) {
            deptIds.add(dept.getId());
            getDeptAll(dept.getId(), deptIds);
        }
    }


}




